package xml.saxParserExample;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class BooksSAXHandler extends DefaultHandler {

	private static Map<String, Book> booksMap = new HashMap<String, Book>();

	private Book book = null;

	private StringBuilder currentPath = new StringBuilder("/");

	private static final String NAME_PATH = "/Books/Book/name/strings/entry/value/";

	private static final String AUTHOR_PATH = "/Books/Book/Author/entry/value/";

	private static final String ELEMENT_BOOK = "Book";

	private static final String ELEMENT_ID = "id";
	
	private static final String ICON_PATH = "/Books/Book/icon/url/";

	public static Book getBook(String id) {
		return booksMap.get(id);
	}

	public static String[] getBookIDs(){
		return booksMap.keySet().toArray(new String[0]);
	}
	
	private static Image getImage(String imageUrl){
		FileInputStream stream = null;
		Image image = null;
		try {
			stream = new FileInputStream(imageUrl);
			image = new Image(Display.getCurrent(), stream);
		} catch (IOException e)
		{
			e.printStackTrace();
		}
		finally{
			if(null != stream)
			{
				try {
					stream .close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return image;
	}


	public static void refresh()
	{
		InputStream stream;
		try {
			stream = new FileInputStream("books.xml");
			SAXParserFactory saxfac = SAXParserFactory.newInstance();
			try {
				SAXParser saxParser = saxfac.newSAXParser();
				saxParser.parse(stream, new BooksSAXHandler());
			} catch (ParserConfigurationException e) {
				e.printStackTrace();
			} catch (SAXException e) {
				e.printStackTrace();
			} catch(FileNotFoundException e)
			{
				e.printStackTrace();
			} catch(IOException e)
			{
				e.printStackTrace();
			}
			for(String id : BooksSAXHandler.getBookIDs())
			{
				Book book = BooksSAXHandler.getBook(id);
				System.out.println(book.toString());
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {

		currentPath.append(qName + "/");
		if (qName.equals(ELEMENT_BOOK)) {
			book = new Book();
			if (attributes.getQName(0).equals(ELEMENT_ID)) {
				book.setID(attributes.getValue(ELEMENT_ID));
			}
		}
	}

	public void endElement(String uri, String localName, String qName)

	throws SAXException {

		currentPath
				.delete(currentPath.lastIndexOf(qName), currentPath.length());
		if (qName.equals(ELEMENT_BOOK)) {
			booksMap.put(book.getID(), book);
			book = null;

		}
	}

	public void characters(char[] ch, int start, int length)

	throws SAXException {
		if (currentPath.toString().equals(NAME_PATH)) {
			book.setName(new String(ch, start, length));
		} else if (currentPath.toString().equals(AUTHOR_PATH)) {
			book.setAuthor(new String(ch, start, length));
		} else if(currentPath.toString().equals(ICON_PATH)){
			book.setImage(getImage(new String(ch, start, length)));
		}
	}
}
